package com.dp.medical.medicalstore.model.obj.medicalstore;

import java.io.Serializable;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;

import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.hibernate.proxy.HibernateProxy;

import com.dp.medical.medicalstore.model.obj.medicalstore.iface.ISupplier;


/** 
 * Object mapping for hibernate-handled table: supplier.
 * @author autogenerated
 */

@Entity
@Table(name = "supplier", catalog = "medicalstore")
public class Supplier implements Cloneable, Serializable,  ISupplier {

	/** Serial Version UID. */
	private static final long serialVersionUID = -558955761L;

	/** Use a WeakHashMap so entries will be garbage collected once all entities 
		referring to a saved hash are garbage collected themselves. */
	private static final Map<Serializable, Integer> SAVED_HASHES =
		Collections.synchronizedMap(new WeakHashMap<Serializable, Integer>());
	
	/** hashCode temporary storage. */
	private volatile Integer hashCode;
	

	/** Field mapping. */
	private String address;
	/** Field mapping. */
	private Integer id = 0; // init for hibernate bug workaround
	/** Field mapping. */
	private Set<Medicine> medicines = new HashSet<Medicine>();

	/** Field mapping. */
	private String name;
	/** Field mapping. */
	private String phone;
	/** Field mapping. */
	private Set<Purchaseinvoice> purchaseinvoices = new HashSet<Purchaseinvoice>();

	/** Field mapping. */
	private Suppliertype typeid;
	/**
	 * Default constructor, mainly for hibernate use.
	 */
	public Supplier() {
		// Default constructor
	} 

	/** Constructor taking a given ID.
	 * @param id to set
	 */
	public Supplier(Integer id) {
		this.id = id;
	}
	
	/** Constructor taking a given ID.
	 * @param id Integer object;
	 * @param name String object;
	 * @param typeid Suppliertype object;
	 */
	public Supplier(Integer id, String name, Suppliertype typeid) {

		this.id = id;
		this.name = name;
		this.typeid = typeid;
	}
	
 


 
	/** Return the type of this class. Useful for when dealing with proxies.
	* @return Defining class.
	*/
	@Transient
	public Class<?> getClassType() {
		return Supplier.class;
	}
 

    /**
     * Return the value associated with the column: address.
	 * @return A String object (this.address)
	 */
	@Basic( optional = true )
	@Column( length = 200  )
	public String getAddress() {
		return this.address;
		
	}
	

  
    /**  
     * Set the value related to the column: address.
	 * @param address the address value you wish to set
	 */
	public void setAddress(final String address) {
		this.address = address;
	}

    /**
     * Return the value associated with the column: id.
	 * @return A Integer object (this.id)
	 */
    @Id 
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Basic( optional = false )
	@Column( name = "id", nullable = false  )
	public Integer getId() {
		return this.id;
		
	}
	

  
    /**  
     * Set the value related to the column: id.
	 * @param id the id value you wish to set
	 */
	public void setId(final Integer id) {
		// If we've just been persisted and hashCode has been
		// returned then make sure other entities with this
		// ID return the already returned hash code
		if ( (this.id == null || this.id == 0) &&
				(id != null) &&
				(this.hashCode != null) ) {
		SAVED_HASHES.put( id, this.hashCode );
		}
		this.id = id;
	}

    /**
     * Return the value associated with the column: medicine.
	 * @return A Set&lt;Medicine&gt; object (this.medicine)
	 */
 	@OneToMany( fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE }, mappedBy = "supplierid"  )
 	@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE})
	@Basic( optional = false )
	@Column( nullable = false  )
	public Set<Medicine> getMedicines() {
		return this.medicines;
		
	}
	
	/**
	 * Adds a bi-directional link of type Medicine to the medicines set.
	 * @param medicine item to add
	 */
	public void addMedicine(Medicine medicine) {
		medicine.setSupplierid(this);
		this.medicines.add(medicine);
	}

  
    /**  
     * Set the value related to the column: medicine.
	 * @param medicine the medicine value you wish to set
	 */
	public void setMedicines(final Set<Medicine> medicine) {
		this.medicines = medicine;
	}

    /**
     * Return the value associated with the column: name.
	 * @return A String object (this.name)
	 */
	@Basic( optional = false )
	@Column( nullable = false, length = 200  )
	public String getName() {
		return this.name;
		
	}
	

  
    /**  
     * Set the value related to the column: name.
	 * @param name the name value you wish to set
	 */
	public void setName(final String name) {
		this.name = name;
	}

    /**
     * Return the value associated with the column: phone.
	 * @return A String object (this.phone)
	 */
	@Basic( optional = true )
	@Column( length = 20  )
	public String getPhone() {
		return this.phone;
		
	}
	

  
    /**  
     * Set the value related to the column: phone.
	 * @param phone the phone value you wish to set
	 */
	public void setPhone(final String phone) {
		this.phone = phone;
	}

    /**
     * Return the value associated with the column: purchaseinvoice.
	 * @return A Set&lt;Purchaseinvoice&gt; object (this.purchaseinvoice)
	 */
 	@OneToMany( fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE }, mappedBy = "supplierid"  )
 	@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE})
	@Basic( optional = false )
	@Column( nullable = false  )
	public Set<Purchaseinvoice> getPurchaseinvoices() {
		return this.purchaseinvoices;
		
	}
	
	/**
	 * Adds a bi-directional link of type Purchaseinvoice to the purchaseinvoices set.
	 * @param purchaseinvoice item to add
	 */
	public void addPurchaseinvoice(Purchaseinvoice purchaseinvoice) {
		purchaseinvoice.setSupplierid(this);
		this.purchaseinvoices.add(purchaseinvoice);
	}

  
    /**  
     * Set the value related to the column: purchaseinvoice.
	 * @param purchaseinvoice the purchaseinvoice value you wish to set
	 */
	public void setPurchaseinvoices(final Set<Purchaseinvoice> purchaseinvoice) {
		this.purchaseinvoices = purchaseinvoice;
	}

    /**
     * Return the value associated with the column: typeid.
	 * @return A Suppliertype object (this.typeid)
	 */
	@ManyToOne( cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.LAZY )
	@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE})
	@Basic( optional = false )
	@JoinColumn(name = "TypeId", nullable = false )
	public Suppliertype getTypeid() {
		return this.typeid;
		
	}
	

  
    /**  
     * Set the value related to the column: typeid.
	 * @param typeid the typeid value you wish to set
	 */
	public void setTypeid(final Suppliertype typeid) {
		this.typeid = typeid;
	}


   /**
    * Deep copy.
	* @return cloned object
	* @throws CloneNotSupportedException on error
    */
    @Override
    public Supplier clone() throws CloneNotSupportedException {
		
        final Supplier copy = (Supplier)super.clone();

		copy.setAddress(this.getAddress());
		copy.setId(this.getId());
		if (this.getMedicines() != null) {
			copy.getMedicines().addAll(this.getMedicines());
		}
		copy.setName(this.getName());
		copy.setPhone(this.getPhone());
		if (this.getPurchaseinvoices() != null) {
			copy.getPurchaseinvoices().addAll(this.getPurchaseinvoices());
		}
		copy.setTypeid(this.getTypeid());
		return copy;
	}
	


	/** Provides toString implementation.
	 * @see java.lang.Object#toString()
	 * @return String representation of this class.
	 */
	@Override
	public String toString() {
		StringBuffer sb = new StringBuffer();
		
		sb.append("address: " + this.getAddress() + ", ");
		sb.append("id: " + this.getId() + ", ");
		sb.append("name: " + this.getName() + ", ");
		sb.append("phone: " + this.getPhone() + ", ");
		return sb.toString();		
	}


	/** Equals implementation. 
	 * @see java.lang.Object#equals(java.lang.Object)
	 * @param aThat Object to compare with
	 * @return true/false
	 */
	@Override
	public boolean equals(final Object aThat) {
		Object proxyThat = aThat;
		
		if ( this == aThat ) {
			 return true;
		}

		
		if (aThat instanceof HibernateProxy) {
 			// narrow down the proxy to the class we are dealing with.
 			try {
				proxyThat = ((HibernateProxy) aThat).getHibernateLazyInitializer().getImplementation(); 
			} catch (org.hibernate.ObjectNotFoundException e) {
				return false;
		   	}
		}
		if (aThat == null)  {
			 return false;
		}
		
		final Supplier that; 
		try {
			that = (Supplier) proxyThat;
			if ( !(that.getClassType().equals(this.getClassType()))){
				return false;
			}
		} catch (org.hibernate.ObjectNotFoundException e) {
				return false;
		} catch (ClassCastException e) {
				return false;
		}
		
		
		boolean result = true;
		result = result && (((this.getId() == null) && ( that.getId() == null)) || (this.getId() != null  && this.getId().equals(that.getId())));
		result = result && (((getAddress() == null) && (that.getAddress() == null)) || (getAddress() != null && getAddress().equals(that.getAddress())));
		result = result && (((getName() == null) && (that.getName() == null)) || (getName() != null && getName().equals(that.getName())));
		result = result && (((getPhone() == null) && (that.getPhone() == null)) || (getPhone() != null && getPhone().equals(that.getPhone())));
		result = result && (((getTypeid() == null) && (that.getTypeid() == null)) || (getTypeid() != null && getTypeid().getId().equals(that.getTypeid().getId())));	
		return result;
	}
	
	/** Calculate the hashcode.
	 * @see java.lang.Object#hashCode()
	 * @return a calculated number
	 */
	@Override
	public int hashCode() {
		if ( this.hashCode == null ) {
			synchronized ( this ) {
				if ( this.hashCode == null ) {
					Integer newHashCode = null;

					if ( getId() != null ) {
					newHashCode = SAVED_HASHES.get( getId() );
					}
					
					if ( newHashCode == null ) {
						if ( getId() != null && getId() != 0) {
							newHashCode = getId();
						} else {

						}
					}
					
					this.hashCode = newHashCode;
				}
			}
		}
	return this.hashCode;
	}
	

	
}
